
// import * as d3 from "../lib/d3.js";
import * as d3 from "d3";
import {copyTypedArray} from "../util/arrays.js";

export function createMask(globe, viewboxAgent) {
    if (!globe) return null;

    console.time("render mask");

    // Create a detached canvas, ask the model to define the mask polygon, then fill with an opaque color.
    // UNDONE: does it really make sense to create a new canvas each time?
    const {width, height} = viewboxAgent.value();
    const canvas = d3.select(document.createElement("canvas")).attr("width", width).attr("height", height).node();
    const context = globe.defineMask(canvas.getContext("2d"));  // CONSIDER: convert defineMask to "fillRenderer"
    context.fillStyle = "rgba(255, 0, 0, 1)";
    context.fill();

    // d3.select("#display").node().appendChild(canvas);  // make mask visible for debugging

    // Grab a _copy_ of the ImageData. Works around a Chrome bug where holding onto the result of getImageData
    // sometimes results in a blank screen, presumably because the associated detached canvas is garbage collected.
    const imageData = context.createImageData(width, height), data = imageData.data;  // layout: [r, g, b, a, ...]
    copyTypedArray(data, context.getImageData(0, 0, width, height).data);
    //const imageData = context.getImageData(0, 0, width, height), data = imageData.data;  // layout: [r, g, b, a, ...]

    console.timeEnd("render mask");
    return {
        imageData: imageData,
        isVisible: function(x, y) {
            const i = (y * width + x) * 4;
            return data[i + 3] > 0;  // non-zero alpha means pixel is visible
        },
        set: function(x, y, rgba) {
            const i = (y * width + x) * 4;
            data[i    ] = rgba[0];
            data[i + 1] = rgba[1];
            data[i + 2] = rgba[2];
            data[i + 3] = rgba[3];
            return this;
        },
    };
}
